home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 February: Tool Chest / Apple_Developer_Group_CD_Series_February_1998_Tool_Chest.iso / Sample Code / Sound PreMixer effect / ComponentDispatch.c < prev    next >
Encoding:
Text File  |  1997-06-18  |  12.3 KB  |  302 lines  |  [TEXT/CWIE]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Common routines for dispatching for any sound component
  5. **
  6. **    by Mark Cookson, Apple Developer Technical Support
  7. **
  8. **    File:    ComponentDispatch.c
  9. **
  10. **    Copyright ©1996 Apple Computer, Inc.
  11. **    All rights reserved.
  12. **
  13. **    You may incorporate this sample code into your applications without
  14. **    restriction, though the sample code has been provided "AS IS" and the
  15. **    responsibility for its operation is 100% yours.  However, what you are
  16. **    not permitted to do is to redistribute the source as "Apple Sample
  17. **    Code" after having made changes. If you're going to re-distribute the
  18. **    source, we require that you make it clear in the source that the code
  19. **    was descended from Apple Sample Code, but that you've made changes.
  20. */
  21.  
  22.  
  23. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  24. //    Sound Component Function Prototypes
  25.  
  26. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  27. // component stuff
  28.  
  29. static pascal ComponentResult __SoundComponentOpen(void *unused1, ComponentInstance self);
  30. static pascal ComponentResult __SoundComponentClose(SoundComponentGlobalsPtr globals, ComponentInstance self);
  31. static pascal ComponentResult __SoundComponentRegister(SoundComponentGlobalsPtr globals);
  32. static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector);
  33.  
  34. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. // basic stuff
  36.  
  37. static pascal ComponentResult __SoundComponentSetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance source);
  38. static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source);
  39. static pascal ComponentResult __SoundComponentGetSourceData(SoundComponentGlobalsPtr globals, SoundComponentDataPtr *sourceData);
  40. static pascal ComponentResult __SoundComponentSetOutput(SoundComponentGlobalsPtr globals, SoundComponentDataPtr requested, SoundComponentDataPtr *actual);
  41.  
  42. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  43. // info methods
  44.  
  45. static pascal ComponentResult __SoundComponentGetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr);
  46.  
  47. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  48. // control methods
  49.  
  50. static pascal ComponentResult __SoundComponentStopSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources);
  51. static pascal ComponentResult __SoundComponentPlaySourceBuffer(SoundComponentGlobalsPtr globals, SoundSource sourceID, SoundParamBlockPtr pb, long actions);
  52.  
  53.  
  54. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  55. // types
  56. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  57.  
  58. #if GENERATINGCFM
  59.  
  60. // These structs are use in PowerMac builds to cast the
  61. // ComponentParameters passed into our component's entry point.
  62.  
  63. enum {
  64.     uppSoundComponentEntryPointProcInfo = kPascalStackBased
  65.         | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  66.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ComponentParameters *)))
  67.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *)))
  68. };
  69.  
  70. // These are used to create the routine descriptor to call each function.
  71.  
  72. enum {
  73.         uppSoundComponentOpenProcInfo = kPascalStackBased
  74.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  75.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *)))
  76.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ComponentInstance)))
  77. };
  78.  
  79. enum {
  80.         uppSoundComponentCloseProcInfo = kPascalStackBased
  81.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  82.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  83.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ComponentInstance)))
  84. };
  85.  
  86. enum {
  87.         uppSoundComponentRegisterProcInfo = kPascalStackBased
  88.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  89.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  90. };
  91.  
  92. enum {
  93.         uppSoundComponentSetSourceProcInfo = kPascalStackBased
  94.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  95.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  96.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  97.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ComponentInstance)))
  98. };
  99.  
  100. enum {
  101.         uppSoundComponentGetSourceProcInfo = kPascalStackBased
  102.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  103.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  104.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  105.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ComponentInstance*)))
  106. };
  107.  
  108. enum {
  109.         uppSoundComponentGetSourceDataProcInfo = kPascalStackBased
  110.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  111.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  112.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  113. };
  114.  
  115. enum {
  116.         uppSoundComponentSetOutputProcInfo = kPascalStackBased
  117.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  118.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  119.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  120.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundComponentDataPtr)))
  121. };
  122.  
  123. enum {
  124.         uppSoundComponentGetInfoProcInfo = kPascalStackBased
  125.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  126.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  127.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  128.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(OSType)))
  129.                 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void *)))
  130. };
  131.  
  132. enum {
  133.         uppSoundComponentStopSourceProcInfo = kPascalStackBased
  134.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  135.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  136.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short)))
  137.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundSource)))
  138. };
  139.  
  140. enum {
  141.         uppSoundComponentPlaySourceBufferProcInfo = kPascalStackBased
  142.                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
  143.                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SoundComponentGlobalsPtr)))
  144.                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SoundSource)))
  145.                 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SoundParamBlockPtr)))
  146.                 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  147. };
  148.  
  149. // this macro will create a global structure of type RoutineDescriptor
  150.  
  151. #define DeclareRoutineDescriptor(info, proc)                                    \
  152.     RoutineDescriptor g##proc##RD = BUILD_ROUTINE_DESCRIPTOR(info, proc)
  153.  
  154. #define GetComponentFunction(proc)    (&g##proc##RD)
  155.  
  156. DeclareRoutineDescriptor(uppSoundComponentRegisterProcInfo, __SoundComponentRegister);
  157. DeclareRoutineDescriptor(uppSoundComponentCloseProcInfo, __SoundComponentClose);
  158. DeclareRoutineDescriptor(uppSoundComponentOpenProcInfo, __SoundComponentOpen);
  159. DeclareRoutineDescriptor(uppSoundComponentSetSourceProcInfo, __SoundComponentSetSource);
  160. DeclareRoutineDescriptor(uppSoundComponentGetSourceProcInfo, __SoundComponentGetSource);
  161. DeclareRoutineDescriptor(uppSoundComponentGetSourceDataProcInfo, __SoundComponentGetSourceData);
  162. DeclareRoutineDescriptor(uppSoundComponentSetOutputProcInfo, __SoundComponentSetOutput);
  163. DeclareRoutineDescriptor(uppSoundComponentGetInfoProcInfo, __SoundComponentGetInfo);
  164. DeclareRoutineDescriptor(uppSoundComponentStopSourceProcInfo, __SoundComponentStopSource);
  165. DeclareRoutineDescriptor(uppSoundComponentPlaySourceBufferProcInfo, __SoundComponentPlaySourceBuffer);
  166.  
  167.  
  168. #else //GENERATING68K
  169.  
  170. #define GetComponentFunction(proc)    (ComponentFunctionUPP)(proc)
  171.  
  172. #endif
  173.  
  174. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  175. //    Sound Component Entry Point
  176. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177.  
  178. // in 68k (non-CFM) the entry point is defined to be the SoundComponentEntryPoint
  179. // in PowerPC the entry point is a Routine Descriptor pointing to SoundComponentEntryPoint
  180.  
  181. //pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals);
  182.  
  183. #if !GENERATINGCFM
  184. #define SoundComponentDispatcher SoundComponentEntryPoint
  185. #else
  186. pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals);
  187. RoutineDescriptor SoundComponentEntryPoint = BUILD_ROUTINE_DESCRIPTOR(uppSoundComponentEntryPointProcInfo, SoundComponentDispatcher);
  188. #endif
  189.  
  190. pascal ComponentResult SoundComponentDispatcher(ComponentParameters *params, SoundComponentGlobalsPtr globals)
  191. {
  192.     ComponentResult                result;
  193.     short                        selector = params->what;
  194.  
  195.     if (selector < 0)
  196.         switch (selector - kComponentRegisterSelect)    // standard component selectors
  197.         {
  198.             case kComponentRegisterSelect - kComponentRegisterSelect:
  199.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentRegister));
  200.                 break;
  201.  
  202.             case kComponentVersionSelect - kComponentRegisterSelect:
  203.                 return (kSoundComponentVersion);
  204.                 break;
  205.  
  206.             case kComponentCanDoSelect - kComponentRegisterSelect:
  207.                 result = __SoundComponentCanDo(0, *((short *) ¶ms->params[0]));
  208.                 break;
  209.  
  210.             case kComponentCloseSelect - kComponentRegisterSelect:
  211.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentClose));
  212.                 break;
  213.  
  214.             case kComponentOpenSelect - kComponentRegisterSelect:
  215.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentOpen));
  216.                 break;
  217.  
  218.             default:
  219.                 result = badComponentSelector;
  220.                 break;
  221.         }
  222.     else if (selector < kDelegatedSoundComponentSelectors)            // selectors that cannot be delegated
  223.         switch (selector)
  224.         {
  225.             case kSoundComponentSetSourceSelect:
  226.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentSetSource));
  227.                 break;
  228.  
  229.             case kSoundComponentGetSourceSelect:
  230.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetSource));
  231.                 break;
  232.  
  233.             case kSoundComponentGetSourceDataSelect:
  234.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetSourceData));
  235.                 break;
  236.  
  237.             case kSoundComponentSetOutputSelect:
  238.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentSetOutput));
  239.                 break;
  240.  
  241.             default:
  242.                 result = badComponentSelector;
  243.                 break;
  244.         }
  245.     else                                                    // selectors that can be delegated
  246.         switch (selector)
  247.         {
  248.             case kSoundComponentGetInfoSelect:
  249.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentGetInfo));
  250.                 break;
  251.  
  252.             case kSoundComponentStopSourceSelect:
  253.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentStopSource));
  254.                 break;
  255.  
  256.             case kSoundComponentPlaySourceBufferSelect:
  257.                 result = CallComponentFunctionWithStorage((Handle) globals, params, GetComponentFunction(__SoundComponentPlaySourceBuffer));
  258.                 break;
  259.  
  260.             default:
  261.                 result = DelegateComponentCall(params, globals->sourceComponent);
  262.                 break;
  263.         }
  264.  
  265.     return (result);
  266. }
  267.  
  268.  
  269. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  270. static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector)
  271. {
  272. #pragma unused (unused1)
  273.  
  274.     ComponentResult        result;
  275.  
  276.     switch (selector)
  277.     {
  278.         case kComponentRegisterSelect:
  279.         case kComponentVersionSelect:
  280.         case kComponentCanDoSelect:
  281.         case kComponentCloseSelect:
  282.         case kComponentOpenSelect:
  283.         case kSoundComponentSetSourceSelect:
  284.         case kSoundComponentGetSourceSelect:
  285.         case kSoundComponentGetSourceDataSelect:
  286.         case kSoundComponentSetOutputSelect:
  287.         // selectors that can be delegated
  288.         case kSoundComponentGetInfoSelect:
  289.         case kSoundComponentStopSourceSelect:
  290.         case kSoundComponentPlaySourceBufferSelect:
  291.             result = true;
  292.             break;
  293.  
  294.         default:
  295.             result = false;
  296.             break;
  297.     }
  298.  
  299.     return (result);
  300. }
  301.  
  302.